package net.tv90.shoppingserver.service;

import lombok.extern.slf4j.Slf4j;
import net.tv90.shoppingserver.dao.GoodRepository;
import net.tv90.shoppingserver.exception.ServerException;
import net.tv90.shoppingserver.model.domain.Good;
import net.tv90.shoppingserver.model.dto.GoodAddDTO;
import net.tv90.shoppingserver.model.dto.GoodQueryDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataSize;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class GoodService {

    private final Path rootLoc = Paths.get("assets/images");
    private final String[] suffix = {"jpe", "jpg", "jpeg", "gif", "png", "bmp", "ico", "svg", "svgz", "tif", "tiff", "webp"};

    @Autowired
    GoodRepository goodRepository;

    @Value("${spring.servlet.multipart.max-file-size}")
    private String fileMaxSize;

    public void addGood(GoodAddDTO dto) {
        String imageUrl;
        try {
            imageUrl = uploadImage(dto.getImage());
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServerException(e.getMessage());
        }
        Good good = Good.builder()
                .name(dto.getName())
                .description(dto.getDescription())
                .price(dto.getPrice())
                .stock(dto.getStock())
                .image(imageUrl)
                .build();
        goodRepository.save(good);
    }

    public List<Good> queryGoods(GoodQueryDTO dto) {
        if (dto.getPage() == null || dto.getPage() < 1) {
            dto.setPage(1);
        }
        if (dto.getPageNum() == null || dto.getPageNum() < 10 || dto.getPageNum() > 30) {
            dto.setPageNum(10);
        }
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageNum());
        Sort sort = dto.getDesc() == 1 ? Sort.by(dto.getOrderBy()).descending() : Sort.by(dto.getOrderBy()).ascending();
        Page<Good> goodPage = goodRepository.findGoodsByConditions(
                dto.getName(),
                dto.getPriceStart(),
                dto.getPriceEnd(),
                dto.getStockStart(),
                dto.getStockEnd(),
                pageRequest,
                sort
        );
        return goodPage.getContent();
    }

    public Integer queryNum(GoodQueryDTO dto) {
        return goodRepository.countGoodsByConditions(
                dto.getName(),
                dto.getPriceStart(),
                dto.getPriceEnd(),
                dto.getStockStart(),
                dto.getStockEnd()
        );
    }

    public String uploadImage(MultipartFile file) throws IOException {

        if (file == null || file.getOriginalFilename() == null || file.isEmpty()) {
            throw new IOException("文件不能为空");
        }

        String oriName = file.getOriginalFilename();
        String ext = StringUtils.getFilenameExtension(oriName);

        boolean isLegal = false;
        for (String s : suffix) {
            if (s.equalsIgnoreCase(ext)) {
                isLegal = true;
                break;
            }
        }
        if (!isLegal) {
            throw new IOException("文件格式不合法");
        }
        if (file.getSize() > DataSize.parse(fileMaxSize).toBytes()) {
            throw new IOException("文件过大");
        }

        String datePrefix = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String url = datePrefix + "/" + UUID.randomUUID() + "." + ext;

        try {
            Files.createDirectories(rootLoc.resolve(datePrefix));
            file.transferTo(rootLoc.resolve(url));
        } catch (IOException e) {
            Files.createDirectories(rootLoc);
            throw new IOException("服务器内部错误，请联系管理员");
        }

        return "/images/" + url;
    }

    public Good queryGoodById(Integer id) {
        return goodRepository.findById(id)
                .orElseThrow(() -> new ServerException("未查询到食物", HttpStatus.NOT_FOUND));
    }

}
